package graphics.rasterizing.camera;

import static util.MatrixOperationsF.cloo;
import static util.MatrixOperationsF.cross_product;
import static util.MatrixOperationsF.dist;
import static util.MatrixOperationsF.multiply;
import static util.MatrixOperationsF.negate;
import static util.Transformations.ones;
import static util.Transformations.transform3DTranslate;

/**
 * A class representing a camera position. Once a CameraPosition object is
 * created it will always give the same results for its methods.
 */
public class CameraPosition {
	/**
	 * Standard constructor, the following is expected: Arrays of length 4
	 * representing a point in[x,y,z,1].
	 **/
	public CameraPosition(float[] origin, float[] orientation,
			float[] viewdirection) {

		_origin = cloo(origin);
		_orientation = cloo(orientation);
		_viewDirection = cloo(viewdirection);
	}

	private float[] _orientation;
	private float[] _origin;
	private float[] _viewDirection;

	public float[] getOrigin() {
		return cloo(_origin);
	}

	public float[] getViewDiretion() {
		return cloo(_viewDirection);
	}

	public float[] getOrientation() {
		return cloo(_orientation);
	}

	/**
	 * Returns the transformation to the axis defined by the viewing origin
	 * orientation and direction. [0,0,0,1] -> origin The transformation
	 * 
	 * @return
	 */
	public float[][] matrix() {
		float[] e = cloo(getOrigin(), 3);
		float[] g = cloo(getViewDiretion(), 3);
		float[] t = cloo(getOrientation(), 3);
		float[] w = multiply(g, 1 / -dist(g));
		float[] u = multiply(cross_product(t, w), 1 / dist(cross_product(t, w)));
		float[] v = cross_product(w, u);
		float[][] translate = transform3DTranslate(negate(e));
		float[][] align = ones(4);
		int x = 0;
		int y = 1;
		int z = 2;
		align[0][0] = u[x];
		align[0][1] = u[y];
		align[0][2] = u[z];
		align[1][0] = v[x];
		align[1][1] = v[y];
		align[1][2] = v[z];
		align[2][0] = w[x];
		align[2][1] = w[y];
		align[2][2] = w[z];
		return multiply(align, translate);
	}

}
